---
title: 前后端对接规范
date: '2023-04-01 12:12:12'
tags: ['规范']
draft: false
summary: 一、接口返回值 1.1 HTTP 状态码 状态码分类： 分类描述 --信息，服务器收到请求，需要请求者继续执行操作 成功，操作被成功接收并处理 重定向，需要进一步的操作以完成请求 客户端错误，请求包含语法错误或无法完成请求 服务器错误，服务器在处理请求的过程中发生了错误HTTP 特殊状态码判断...
---

### 一、接口返回值

#### 1.1 HTTP 状态码

1. 状态码分类：
   | 分类|分类描述|对接形式|
   |---|---|---|
   | 1\*\*| 信息，服务器收到请求，需要请求者继续执行操作|\*|
   | 2\*\*| 成功，操作被成功接收并处理|\*|
   | 3\*\*| 重定向，需要进一步的操作以完成请求|\*|
   | 4\*\*| 客户端错误，请求包含语法错误或无法完成请求|如果是参数错误需要返回具体错误信息|
   | 5\*\*| 服务器错误，服务器在处理请求的过程中发生了错误|返回具体报错信息|- HTTP 特殊状态码判断

2. 前端取 HTTP 状态进行判断，后端统一报错或提示形式：
   - 返回 2\*\*，前端默认请求成功，可直接去 HTTP 返回的默认的 data 中数据；
   - 返回 4\*\*或者 5\*\*，前端按照 1.2 中预定格式向用户提示错误信息；

3. 前端直接判断的部分特殊状态码
   |状态码|英文名称|中文描述|提示信息|
   |---|---|---|---|
   |400|Bad Request|客户端请求的语法错误，服务器无法理解|客户端请求的语法错误，服务器无法理解|
   |401|Unauthorized|请求要求用户的身份认证|服务返回提示|
   |403|Forbidden| 服务器理解请求客户端的请求，但是拒绝执行此请求|服务返回提示|
   |404|Not Found| 服务器无法根据客户端的请求找到资源| 服务器无法根据客户端的请求找到资源|
   |408| Request Time-out| 服务器等待客户端发送的请求时间过长，超时|请求超时|
   |411| Length Required| 服务器无法处理客户端发送的不带 Content-Length 的请求信息|请求内容过长|
   |414|Request-URI Too Large|请求的 URI 过长（URI 通常为网址），服务器无法处理|请求地址过长|
   |500|Internal Server Error|服务器内部错误，无法完成请求|服务器内部错误，无法完成请求|
   |502| Bad Gateway| 作为网关或者代理工作的服务器尝试执行请求时，从远程服务器接收到了一个无效的响应|网关或者代理错误|

#### 1.2 返回的数据格式：

1. 返回的基础数据格式：

   ```javascript
   {
   	headers:{},			// http默认格式 - 请求请求头
   	status:200,			// http默认格式 - 请求状态码
   	statusText:'ok',		// http默认格式
   	request:{},			// http默认格式
   	data:{ 				// http请求返回值 - 一下数据为后台返回数据
   		result:{},		// 返回的主题数据 数组或对象
   		meta:{
   				code:200,
   				message:'请求成功！',
   				success:true
   			}
   	}
   }
   ```

1. 返回的列表数据格式：
   ```javascript
   {
   	headers:{},		// http默认格式 - 请求请求头
   	status:200,		// http默认格式 - 请求状态码
   	statusText:'ok',	// http默认格式
   	request:{},		// http默认格式
   	data:{			// http请求返回值 - 一下数据为后台返回数据
   		result:{
   			pageIndex:1,	// 当前页数
   			pageSize:10,	// 每页数量
   			total:2,	// 列表总页数
   			orderBy:{}	// 排序规则
   			condition:{},	// 执行的搜索规则-debug 用
   			permission:[],	// 当前表单的权限标记-可以为对象也可以是权限标记的 code
   			result:[{ 	// http 请求返回值
   				permission:[]// 单条数据的权限标记-可以为对象也可以是权限标记的 code
   			}]
   		},
   		meta:{
   				code:200,
   				message:'请求成功！',
   				success:true
   			}
   	}
   }
   ```
1. 权限标记数据格式：
   - 无论是对模块数据的整体或批量挫折，例如：列表的添加、分配，数据到导入导出，还是对单条数据的操作，例如增删改查，都需要按照 1.2.\*中的格式返回；
   - 返回的单个权限对应格式：

   ```javascript
   {
   	operation:"",// 操作 用于标记操作
   	component:"",// 组件 用于指定前端操作组件
   	name:"",	// name 用于展示按钮文案
   	spare:""	// 备用扩展字段
   }
   ```

1. 项目中标记唯一对象，不管属于任何模块均使用唯一键名，唯一 id 或者 uuid 标记，如发现唯一对象的唯一属性出现多个键名，前端可指定键名让后端修改；

1. 项目中约定数据格式数组，对象后端在程序非报错情况下，务必按照预定格式进行返回，前端可只做第一次数据类型判断直接取值，设计深层对象取值，js 因数据类型报错有后端处理；

1. 项目中数据的对应关系应有具体自定义标示进行对应，不能使用索引对应；

---

### 二、登陆加密及用户信息

#### 2.1 登陆加密形式；

1. 登陆中账号密码不能直接发送，前端也不能直接明文存在本地；
2. ~~前端密码需要两次 md5 加密后再提交：~~

   ```javascript
   import md5 from 'md5.js'
   const password = md5(md5(password))
   ```

   修订 1.0：加密访视如果使用 MD5 形式:需要两次 md5(password + '项目名称-英文') 加密

   ```javascript
   import md5 from 'md5.js'
   const password = md5(md5(password + 'medsci'))
   ```

3. 记住登陆状态优先使用本地存在 token 的形式，后台需要根据项目需求设计 token 时限；

#### 2.2 用户信息

1. 得到用户信息需要验证 cookie 或者 header 中 token；
1. 前端原则上不本地存储用户信息，用户信息应在项目初始化得到放置全局使用；
1. 设计项目限制需要本地存储用户信息的需尽量存到 SessionStorage 如需退出后保持登陆前端 localStorage 应存储用户的 token 而非真实信息;

---

### 三、前后端表单及其他数据校验

#### 3.1 必填参数

1. 后端如未接受到必填参数，应参照 1.2 中 HTTP 状态码（403 或者 412）返回提示信息，提示信息将用于直接向用户展示，故需要指明具体的错误信息；
2. 针对必填参数前端也需要进行判断，如果为得到必填参数则向用户进行对应提示且不发送请求；

#### 3.2 默认参数

1. 默认参数后端应根据约定配置相应的默认逻辑，不能再缺少默认参数时直接抛出异常；
2. 默认参数前端也需要进行处理，如果为得到用户主动修改的参数则向向后台发送默认参数；

#### 3.3 表单校验

1. 表单提交校验时前端和后端都必须进行表单的校验；

#### 3.4 接口权限验证

1. 接口涉及权限的如查看操作敏感数据时后端需要验证用户权限；

- 后端校验应包括：参数校验,权限校验,表单校验

---

### 四、接口及迭代

#### 4.1 接口地址

1. 接口地址迭代时除非设计两个版本逻辑都使用，否者迭代时不可用修改接口地址；
2. 后端在项目开始时需要确定接口地址规范（RESTful 规范等）
3. 接口中至少需要包含：

```javascript
const path = `域名或 ip 端口` / `版本` / `具体的业务功能` / `表名` / `行为`
```

4. 接口的版本已当前正式发布的大版本为准，后端不可用随意修改版本号；

#### 4.2 接口参数

1. 接口参数应避免大量臃余参数，标记唯一对象应尽量采用唯一键值标记；

---

### 五、公共参数

#### 5.1 传参形式

1. 项目涉及多语言环境时，采用请求头中标记的形式，zh 表示中文，en 表示英文：

```javascript
headers: {
  lang: 'zh'
}
```

1. 处采用 cook 进行用户身份认证的情况外，用户身份认证均使用请求头中标记 token 的形式验证：

```javascript
headers:{
            Authorization:*
        }
```

1. 其他公共参数包括：用户选择的项目、角色、部门等或者其他设计用户可修改的全局对象，原则上可以通过 headers 传递的均使用 headers 传递，如涉及中文等其他 headers 不支持的内容，使用 data 传递；

---

### 六、多语言

#### 6.1 多语言配置

1. 项目涉及多语言是应在项目一开始就确定；
1. 项目迭代中添加对语言功能，需要预留所有功能整体测试的时间；

#### 6.2 多语言展示形式

1. 切换语言环境是，后台返回的用于展示的键名不应在不同语言环境下发生改变；

---

### 七、关系映射

#### 7.1 布尔值/数值标记状态

1. 数值/布尔值值标记状态是，不仅要返回数值/布尔值，也要返回对应的标记中文名称;
1. 返回的数值/布尔值需要确定数据类型必须为数值/布尔值，不能为字符串；

#### 7.2 单个状态

1. 单个状态类型采用单个标记不可以多种状态集合标记；

---

### 八、标记设备

#### 8.1 区分不同终端

```javascript
const userAgent = navigator.userAgent
```

1.  收集浏览器，判断浏览器版本标记中无其他终端（微信、app）标记；
1.  微信公众号、微信浏览器，判断浏览器版本标记中包含微信标记
1.  app（待定）

---

### 九、跨客户端保持登陆

#### 9.1 传参形式

1. 跨终端参数传递采用 url 传递；

#### 9.2 参数形式

1. 跨终端传递的参数不可用包括明文或中文，如涉及参数过多或者中文为必要参数时需要提供多个参数转译成 token 和解析 token 参数的接口；

---

### 十、文档编写

#### 10.1 文档形式

1. 使用 swagger 生成 api 文档；
1. 从我们到具体的接口，文档层级最多不要超过三层；
1. 需要在文档中最外层明确前端访问接口的具体域名或者 ip 端口；
1. 需要在 swagger 的文档中提供正确的模拟参数；
1. 涉及多人开发需要在文档中或者另外提供文档明确哪些模块的 api 由谁维护；

#### 10.2 文档维护

1. 文档需要作为项目交付的一部分，项目交付时需要一同交付 api 文档；
1. 项目迭代时文档要同步更新；
